/*******************************************************************************
 * Package: com.song.kkxxpoi.controller
 * Type:    RedisWeb
 * Date:    2022-07-29 23:16
 *
 * 
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.song.kkxxpoi.controller;

import com.song.common.annotation.CurrentLimiter;
import com.song.common.lock.RedisLock;
import com.song.common.response.ResponseVO;
import com.song.common.util.CurrentLimiterUtil;
import com.song.common.util.RedisServiceUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 功能描述：
 *
 * @author Songxianyang
 * @date 2022-07-29 23:16
 */
@Api(tags = "测试Redisson、redis")
@RestController
@Slf4j
public class RedisWeb {
    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedisServiceUtil redisServiceUtil;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 接口限流
     */
    @Resource
    private CurrentLimiterUtil currentLimiterUtil;
    /**
     * 可重入锁
     * @return
     */
    @GetMapping("lock-kcr")
    @ApiOperation("redisson_可重入锁")
    public String testLock() throws InterruptedException {
        RLock lock = redissonClient.getLock("test-Lock");
        lock.lock(11,TimeUnit.SECONDS);
        //boolean b = lock.tryLock(5,10,TimeUnit.SECONDS);
        try {
    
            System.out.println("上锁拉拉"+Thread.currentThread().getName());
            Thread.sleep(10000);
            // 执行业务代码
                return "执行业务代码！";
                
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("解锁锁拉拉"+Thread.currentThread().getName());
            lock.unlock();
        }
        return "s";
    }

    @GetMapping("string-redis-set")
    @ApiOperation("redis存")
    public String stringRedisSet() {
        redisServiceUtil.set("testKey", "songxianyang",60);
        return "ok";
    }
    @GetMapping("string-redis-get")
    @ApiOperation("redis取")
    public String stringRedisGet() {
        return redisServiceUtil.get("testKey");
    }


    // 基于redis实现分布式锁
    @GetMapping("redis-lock-set-nx")
    @ApiOperation("基于redis实现分布式锁")
    public String redisLockSetNx() {

        log.info("我进入了方法！");
        try (RedisLock redisLock = new RedisLock(redisTemplate, "redisKey", 30)) {
            if (redisLock.getLock()) {
                log.info("我进入了锁！！");
                Thread.sleep(15000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("方法执行完成");
        return "方法执行完成";
    }
    @GetMapping("redis-lua-limiter")
    @ApiOperation("接口限流-工具类")
    public ResponseVO<String> redisLuaLimit() {
        currentLimiterUtil.limitAccess("redisLuaLimit", 3);
        return ResponseVO.success(redisServiceUtil.get("name")) ;
    }

    @GetMapping("redis-lua-limiter-annotation")
    @ApiOperation("接口限流-注解-aop")
    @CurrentLimiter(limit = 3)
    public ResponseVO<String> redisLuaLimitAnnotation() {
        String name = redisServiceUtil.get("name");
        return ResponseVO.success(name) ;
    }
}
